package br.com.sicoob.cedente.transacao;

import br.com.bancoob.cedente.util.ByteUtil;
import br.com.bancoob.cedente.util.Desafio;
import br.com.sicoob.model.Mensagem;

public final class TransacaoEstabeleceSessao extends TransacaoImpl {

		
	public TransacaoEstabeleceSessao(String cooperativa, String idUsuario,
			ComunicacaoBasica comunicacaoBasica, String sequencialTerminal,
			String numeroPac, String codigoCanal, String terminal,
			String idProduto, int quantidadeTentativas,
			int tempoMaxEntreTentativas) throws NegocioException {
		super("LGCED", cooperativa, idUsuario, comunicacaoBasica,
				sequencialTerminal, numeroPac, codigoCanal, terminal,
				idProduto, quantidadeTentativas, tempoMaxEntreTentativas);
		
	}

	protected int transmitir(Mensagem msg) {

		byte[] msgResposta = null;

		try {
			this.setDadosHeaderTrn(msg);

			byte[] msgEnvio = montaMsg(getFormato(), msg, false);
			String strTcp = "SCED" + "S001"
					+ Util.insereZeros(msgEnvio.length, 8);
			msgEnvio = ByteUtil.concatenaBytes(strTcp.getBytes(), msgEnvio);

			comunicacao.enviarReceber(msgEnvio);
			msgResposta = comunicacao.getPayload();

		} catch (Exception e) {
			e.printStackTrace();
			msg.setValor(Rotulos.ERRO_MENSAGEM, e.getMessage());
			return TransacaoImpl.TRN_COM_ERRO;
		}

		return isRespostaSessaoOk(msgResposta, msg);
	}

	/*
	 * Configura os dados necessarios para se estabelecer uma conexao com o
	 * SRTB.
	 */
	public void setDadosHeaderTrn(Mensagem msg) throws Exception {

		msg.setValor(Rotulos.TRANSACAO, getNomeTransacao());
		msg.setValor(Rotulos.VERSAO, "001");

		msg.setValor(Rotulos.COOPERATIVA, vars.getCooperativa());
		msg.setValor(Rotulos.NUMERO_PAC, vars.getNumeroPac());
		msg.setValor(Rotulos.NUMERO_CLIENTE, vars.getIdUsuario());

		msg.setValor(Rotulos.ID_SESSAO, "cedente");
		msg.setValor(Rotulos.DESAFIO_SESSAO, getDesafio());

		msg.setValor(Rotulos.CODIGO_CANAL, codigoCanal);
		msg.setValor(Rotulos.ID_PRODUTO, idProduto);

	}

	private byte[] getDesafio() throws Exception {

		byte[] senha = getSenha();

		byte[] hash = ByteUtil.getHash(senha);

		vars.setAESChkChvCripto(hash);

		byte[] dados = ByteUtil.concatenaBytes(vars.getChkAESCripto(),"cedente".getBytes());

		byte[] desafio = AES.cifra(dados, vars.getChvAESCripto());

		return desafio;
	}

	/*
	 * Busca a senha para ser validado do lado servidor.
	 */
	private byte[] getSenha() {

		int cooperativa = (new Integer(vars.getCooperativa())).intValue();
		int pac = (new Integer(vars.getNumeroPac())).intValue();
		int cliente = (new Integer(vars.getIdUsuario())).intValue();

		Desafio desafio = new Desafio();

		return desafio.gerarChave(cooperativa, pac, cliente).getBytes();
	}

	@SuppressWarnings("deprecation")
	protected int isRespostaSessaoOk(byte[] msgResposta, Mensagem msg) {
		byte[] resp = new byte[msgResposta.length - 32];
		byte[] hash = new byte[32];

		System.arraycopy(msgResposta, 0, resp, 0, msgResposta.length - 32);
		System.arraycopy(msgResposta, msgResposta.length - 32, hash, 0, 32);

		int pos = msg.trataHeader(resp, "headerCom");
		msg.trataPayload(resp, pos);

		if (msg.getValor(Rotulos.IND_EXECUCAO).equals("N")) {
			return TransacaoImpl.TRN_COM_ERRO;
		}

		byte[] dados;
		try {
			dados = AES.decifra(msg.getValorBytes(Rotulos.ALEATORIO), vars
					.getChvAESCripto());
		} catch (Exception e) {
			e.printStackTrace();
			return TransacaoImpl.TRN_COM_ERRO;
		}

		if (Util.comparaBytes(dados, vars.getChkAESCripto(), 8) == false) {
			return TransacaoImpl.TRN_COM_ERRO;
		}

		byte[] numAle = new byte[64];
		System.arraycopy(dados, 8, numAle, 0, numAle.length);
		hash = ByteUtil.getHash(numAle);

		msg.setValor(AESChkChvCripto, hash);
		msg.setValor(Rotulos.SESSAO, msg.getValor(Rotulos.SESSAO));

		return TransacaoImpl.TRN_OK;
	}
}